package com.css.zfzx.sjcj.modules.yhdisaster.repository.impl;

import com.css.bpm.platform.api.local.PlatformAPI;
import com.css.bpm.platform.org.dept.repository.entity.DeptEntity;
import com.css.bpm.platform.org.division.repository.DivisionRepository;
import com.css.bpm.platform.org.division.repository.entity.DivisionEntity;
import com.css.bpm.platform.org.role.repository.entity.RoleEntity;
import com.css.bpm.platform.utils.PlatformObjectUtils;
import com.css.bpm.platform.utils.PlatformSessionUtils;
import com.css.zfzx.sjcj.common.utils.PinyinUtil;
import com.css.zfzx.sjcj.common.utils.ServerUtil;
import com.css.zfzx.sjcj.modules.yhdisaster.repository.YhDisasterNativeRepository;
import com.css.zfzx.sjcj.modules.yhdisaster.repository.entity.YhDisasterEntity;
import com.css.zfzx.sjcj.modules.yhdisaster.viewobjects.YhDisasterQueryParams;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;

/**
 * @author lxg
 * @date 2020-11-10
 */
@Repository
@PropertySource("classpath:platform-config.yml")
public class YhDisasterNativeRepositoryImpl<T> implements YhDisasterNativeRepository<T> {
    @PersistenceContext
    private EntityManager em;

    private static final Logger log = LoggerFactory.getLogger(YhDisasterNativeRepositoryImpl.class);

    @Value("${role.superCode}")
    private String superCode;
    @Value("${role.provinceCode}")
    private String provinceCode;
    @Value("${role.cityCode}")
    private String cityCode;
    @Value("${role.areaCode}")
    private String areaCode;
    @Autowired
    private DivisionRepository divisionRepository;
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Value("${spring.jpa.properties.hibernate.jdbc.batch_size}")
    private int BATCH_SIZE;
    //批量插入
    @Override
    @Transactional
    public <S extends T> Iterable<S> batchSave(Iterable<S> var1) {
        Iterator<S> iterator = var1.iterator();
        int index = 0;
        while (iterator.hasNext()){
            em.persist(iterator.next());
            index++;
            if (index % BATCH_SIZE == 0){
                em.flush();
                em.clear();
            }
        }
        if (index % BATCH_SIZE != 0){
            em.flush();
            em.clear();
        }
        return var1;
    }
    //批量插入
    @Transactional
    @Override
    public <S extends T> Iterable<S> batchUpdate(Iterable<S> var1) {
        //TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            Iterator<S> iterator = var1.iterator();
            int index = 0;
            while (iterator.hasNext()) {
                index++;
                if (index % BATCH_SIZE == 0) {
                    em.flush();
                    em.clear();
                    System.out.println("flush end :"+index);
                    //transactionManager.commit(transaction);
                }
                em.merge(iterator.next());

            }
            if (index % BATCH_SIZE != 0) {
                em.flush();
                em.clear();
            }
            //transactionManager.commit(transaction);
        } catch (RuntimeException e) {
            //transactionManager.rollback(transaction);
            log.error(e.getMessage());
        }
        return var1;
    }

    @Override
    public Page<YhDisasterEntity> queryYhDisasters(YhDisasterQueryParams queryParams, int curPage, int pageSize, String type, String sort, String order) {
        String pinyinOfProvince = PinyinUtil.buildProvinceSubfix(queryParams.getProvince());
        StringBuilder sql = new StringBuilder("select * from yh_disaster"+pinyinOfProvince);
        StringBuilder whereSql = new StringBuilder(" where 1=1 ");
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhCode())) {
            whereSql.append(" and yh_code like :yhCode");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhUnit())) {
            whereSql.append(" and yh_unit like :yhUnit");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhProjectName())) {
            whereSql.append(" and yh_project_name like :yhProjectName");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhProjectTask())) {
            whereSql.append(" and yh_project_task like :yhProjectTask");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getProvince())) {
            whereSql.append(" and province = :province");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getCity())) {
            whereSql.append(" and city = :city");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getArea())) {
            whereSql.append(" and area = :area");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhConstructionScale())) {
            whereSql.append(" and yh_construction_scale like :yhConstructionScale");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhEarthFortification())) {
            whereSql.append(" and yh_earth_fortification = :yhEarthfortification");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhFieldType())) {
            whereSql.append(" and yh_field_type = :yhFieldType");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhLotType())) {
            whereSql.append(" and yh_lot_type = :yhLotType");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getReviewStatus())) {
            whereSql.append(" and review_status = :reviewStatus");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getQualityResult())) {
            whereSql.append(" and quality_result = :qualityResult");
        }
        if(!StringUtils.isEmpty(queryParams.getExtends1())){
            whereSql.append(" and extends1 = :extends1");
        }
        String userId = PlatformSessionUtils.getUserId();
        List<RoleEntity> roles = PlatformAPI.getOrgAPI().getUserAPI().getRoles(userId);
        //是否为超级管理员
        boolean containtRole = ServerUtil.isContaintRole(roles, superCode);
        //是否为省级管理员
        boolean containtRolePro = ServerUtil.isContaintRole(roles, provinceCode);
        //是否为市级管理员
        boolean containtRoleCity = ServerUtil.isContaintRole(roles, cityCode);
        //是否为县级管理员
        boolean containtRoleArea= ServerUtil.isContaintRole(roles,areaCode);
        if(!containtRole){
            if (!containtRolePro && !containtRoleCity && !containtRoleArea) {
                whereSql.append(" and creat_user_Id =:userId");
            }
            if(containtRolePro){
                whereSql.append(" and province like :authProvince");
            }
            if(containtRoleCity){
                whereSql.append(" and city like :authCity");
            }
            if(containtRoleArea){
                whereSql.append(" and area like :authArea");
            }
        }
        whereSql.append(" and yh_project_type = :type");
        whereSql.append(" and is_valid = 1");
        whereSql.append(" and review_status =1");
        //whereSql.append(" order by create_time desc");
        if (!PlatformObjectUtils.isEmpty(sort)) {
            whereSql.append(" order by "+sort+" "+order);
        }
        Query query = this.em.createNativeQuery(sql.append(whereSql).toString(), YhDisasterEntity.class);
        StringBuilder countSql = new StringBuilder("select count(*) from yh_disaster"+pinyinOfProvince);
        Query countQuery = this.em.createNativeQuery(countSql.append(whereSql).toString());
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhCode())) {
            query.setParameter("yhCode", "%" + queryParams.getYhCode() + "%");
            countQuery.setParameter("yhCode", "%" + queryParams.getYhCode() + "%");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhUnit())) {
            query.setParameter("yhUnit", "%" + queryParams.getYhUnit() + "%");
            countQuery.setParameter("yhUnit", "%" + queryParams.getYhUnit() + "%");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhProjectName())) {
            query.setParameter("yhProjectName", "%" + queryParams.getYhProjectName() + "%");
            countQuery.setParameter("yhProjectName", "%" + queryParams.getYhProjectName() + "%");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhProjectTask())) {
            query.setParameter("yhProjectTask", "%" + queryParams.getYhProjectTask() + "%");
            countQuery.setParameter("yhProjectTask", "%" + queryParams.getYhProjectTask() + "%");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getProvince())) {
            query.setParameter("province", queryParams.getProvince());
            countQuery.setParameter("province", queryParams.getProvince());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getCity())) {
            query.setParameter("city", queryParams.getCity());
            countQuery.setParameter("city", queryParams.getCity());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getArea())) {
            query.setParameter("area", queryParams.getArea());
            countQuery.setParameter("area", queryParams.getArea());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhConstructionScale())) {
            query.setParameter("yhConstructionScale", "%" + queryParams.getYhConstructionScale() + "%");
            countQuery.setParameter("yhConstructionScale", "%" + queryParams.getYhConstructionScale() + "%");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhEarthFortification())) {
            query.setParameter("yhEarthfortification", queryParams.getYhEarthFortification());
            countQuery.setParameter("yhEarthfortification", queryParams.getYhEarthFortification());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhFieldType())) {
            query.setParameter("yhFieldType", queryParams.getYhFieldType());
            countQuery.setParameter("yhFieldType", queryParams.getYhFieldType());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhLotType())) {
            query.setParameter("yhLotType", queryParams.getYhLotType());
            countQuery.setParameter("yhLotType", queryParams.getYhLotType());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getReviewStatus())) {
            query.setParameter("reviewStatus", queryParams.getReviewStatus());
            countQuery.setParameter("reviewStatus", queryParams.getReviewStatus());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getQualityResult())) {
            query.setParameter("qualityResult", queryParams.getQualityResult());
            countQuery.setParameter("qualityResult", queryParams.getQualityResult());
        }
        if(!StringUtils.isEmpty(queryParams.getExtends1())){
            query.setParameter("extends1", queryParams.getExtends1());
            countQuery.setParameter("extends1", queryParams.getExtends1());
        }
        if(!containtRole){
            if (!containtRolePro && !containtRoleCity && !containtRoleArea) {
                query.setParameter("userId",PlatformSessionUtils.getUserId());
            }
            DeptEntity mainDept = PlatformAPI.getOrgAPI().getUserAPI().getMainDept(userId);
            String divisionId = mainDept.getDivisionId();
            DivisionEntity validDivisionById = divisionRepository.findValidDivisionById(divisionId);
            String divisionName = validDivisionById.getDivisionName();
            if(containtRolePro){
                query.setParameter("authProvince","%"+divisionName+"%");
                countQuery.setParameter("authProvince","%"+divisionName+"%");
            }
            if(containtRoleCity){
                query.setParameter("authCity","%"+divisionName+"%");
                countQuery.setParameter("authCity","%"+divisionName+"%");
            }
            if(containtRoleArea){
                query.setParameter("authArea","%"+divisionName+"%");
                countQuery.setParameter("authArea","%"+divisionName+"%");
            }
        }
        query.setParameter("type",type);
        countQuery.setParameter("type",type);
        Pageable pageable = PageRequest.of(curPage - 1, pageSize);
        query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
        query.setMaxResults(pageable.getPageSize());
        List<YhDisasterEntity> list = query.getResultList();
        BigInteger count = (BigInteger) countQuery.getSingleResult();
        Page<YhDisasterEntity> yhDisasterPage = new PageImpl<>(list, pageable, count.longValue());
        return yhDisasterPage;
    }

    @Override
    public List<YhDisasterEntity> exportYhDisasters(YhDisasterQueryParams queryParams, String type) {
        String provinceSubfix = PinyinUtil.buildProvinceSubfix(queryParams.getProvince());
        StringBuilder sql = new StringBuilder("select * from yh_disaster"+provinceSubfix);
        StringBuilder whereSql = new StringBuilder(" where 1=1 ");
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhCode())) {
            whereSql.append(" and yh_code like :yhCode");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhUnit())) {
            whereSql.append(" and yh_unit like :yhUnit");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhProjectName())) {
            whereSql.append(" and yh_project_name like :yhProjectName");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhProjectTask())) {
            whereSql.append(" and yh_project_task like :yhProjectTask");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getProvince())) {
            whereSql.append(" and province = :province");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getCity())) {
            whereSql.append(" and city = :city");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getArea())) {
            whereSql.append(" and area = :area");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhConstructionScale())) {
            whereSql.append(" and yh_construction_scale like :yhConstructionScale");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhEarthFortification())) {
            whereSql.append(" and yh_earth_fortification = :yhEarthfortification");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhFieldType())) {
            whereSql.append(" and yh_field_type = :yhFieldType");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhLotType())) {
            whereSql.append(" and yh_lot_type = :yhLotType");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getQualityResult())) {
            whereSql.append(" and quality_result = :qualityResult");
        }
        if(!StringUtils.isEmpty(queryParams.getExtends1())){
            whereSql.append(" and extends1 = :extends1");
        }
        String userId = PlatformSessionUtils.getUserId();
        List<RoleEntity> roles = PlatformAPI.getOrgAPI().getUserAPI().getRoles(userId);
        //是否为超级管理员
        boolean containtRole = ServerUtil.isContaintRole(roles, superCode);
        //是否为省级管理员
        boolean containtRolePro = ServerUtil.isContaintRole(roles, provinceCode);
        //是否为市级管理员
        boolean containtRoleCity = ServerUtil.isContaintRole(roles, cityCode);
        //是否为县级管理员
        boolean containtRoleArea= ServerUtil.isContaintRole(roles,areaCode);
        if(!containtRole){
            if (!containtRolePro && !containtRoleCity && !containtRoleArea) {
                whereSql.append(" and creat_user_Id =:userId");
            }
            if(containtRolePro){
                whereSql.append(" and province like :authProvince");
            }
            if(containtRoleCity){
                whereSql.append(" and city like :authCity");
            }
            if(containtRoleArea){
                whereSql.append(" and area like :authArea");
            }
        }
        whereSql.append(" and yh_project_type = :type");
        whereSql.append(" and is_valid = 1");
        whereSql.append(" and review_status =1");
        Query query = this.em.createNativeQuery(sql.append(whereSql).toString(), YhDisasterEntity.class);
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhCode())) {
            query.setParameter("yhCode", "%" + queryParams.getYhCode() + "%");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhUnit())) {
            query.setParameter("yhUnit", "%" + queryParams.getYhUnit() + "%");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhProjectName())) {
            query.setParameter("yhProjectName", "%" + queryParams.getYhProjectName() + "%");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhProjectTask())) {
            query.setParameter("yhProjectTask", "%" + queryParams.getYhProjectTask() + "%");
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getProvince())) {
            query.setParameter("province", queryParams.getProvince());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getCity())) {
            query.setParameter("city", queryParams.getCity());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getArea())) {
            query.setParameter("area", queryParams.getArea());

        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhConstructionScale())) {
            query.setParameter("yhConstructionScale", "%" + queryParams.getYhConstructionScale() + "%");

        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhEarthFortification())) {
            query.setParameter("yhEarthfortification", queryParams.getYhEarthFortification());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhFieldType())) {
            query.setParameter("yhFieldType", queryParams.getYhFieldType());

        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getYhLotType())) {
            query.setParameter("yhLotType", queryParams.getYhLotType());
        }
        if(!PlatformObjectUtils.isEmpty(queryParams.getQualityResult())) {
            query.setParameter("qualityResult", queryParams.getQualityResult());
        }
        if(!StringUtils.isEmpty(queryParams.getExtends1())){
            query.setParameter("extends1", queryParams.getExtends1());
        }
        if(!containtRole){
            if (!containtRolePro && !containtRoleCity && !containtRoleArea) {
                query.setParameter("userId",PlatformSessionUtils.getUserId());
            }
            DeptEntity mainDept = PlatformAPI.getOrgAPI().getUserAPI().getMainDept(userId);
            String divisionId = mainDept.getDivisionId();
            DivisionEntity validDivisionById = divisionRepository.findValidDivisionById(divisionId);
            String divisionName = validDivisionById.getDivisionName();
            if(containtRolePro){
                query.setParameter("authProvince","%"+divisionName+"%");
            }
            if(containtRoleCity){
                query.setParameter("authCity","%"+divisionName+"%");
            }
            if(containtRoleArea){
                query.setParameter("auithArea","%"+divisionName+"%");
            }
        }
        query.setParameter("type",type);
        List<YhDisasterEntity> list = query.getResultList();
        return list;
    }
}
